package com.appspot.battlerafts.servlets.game;

import com.appspot.battlerafts.classes.Game;
import com.appspot.battlerafts.enums.GameState;
import com.appspot.battlerafts.jsons.CheckJoinPremissionJSON;
import com.appspot.battlerafts.jsons.GameDataJSON;
import com.appspot.battlerafts.jsons.ResponseJSON;
import com.appspot.battlerafts.utils.PMF;
import com.google.gson.Gson;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import static com.appspot.battlerafts.utils.Util.returnError;

public class CheckJoinPermission extends HttpServlet {

    class CheckAndGetGameTokenResponseJSON extends ResponseJSON {
        public String token;
    }

    private static final Logger log = Logger.getLogger(CheckJoinPermission.class.getName());

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Gson gson = new Gson();
        String rawInput = request.getParameter("data");
        GameDataJSON registerJSON = gson.fromJson(rawInput, GameDataJSON.class);
        log.info("Reg join from user: " + registerJSON.playerUID);
        log.setLevel(Level.INFO);

        PersistenceManager pm = PMF.get().getPersistenceManager();
        Game game;
        try {
            game = (Game) pm.getObjectById(Game.class, registerJSON.gameID);
            if (IDinRegisteredList(registerJSON, game)) {
                returnError(response, "You (uid: " + registerJSON.playerUID + " ) have already registered to this game!");
                return;
            }

            if (!game.isGamePrivate()) {
                if (game.getNrOfPlayers() == game.getItendedPlayers().size()) {
                    returnError(response, "This game has reached it's maximum nr of players!");
                    return;
                }
                if (IDinIntendedList(registerJSON, game) && !IDinRegisteredList(registerJSON, game)) {
                    addToRegistered(registerJSON, game);
                } else if (!IDinIntendedList(registerJSON, game)) {
                    addToRegistered(registerJSON, game);
                    addToItended(registerJSON, game);
                }
            } else {
                if (!IDinIntendedList(registerJSON, game)) {
                    returnError(response, "This is a private game and you are not an intended player!");
                    return;
                } else {
                    addToRegistered(registerJSON, game);
                }

            }
            game = pm.detachCopy(game);
        } catch (JDOObjectNotFoundException e) {
            log.info(e.toString());
            returnError(response, "The iniator is probably still selecting players. To join again just refresh this page or click the link again!");
            return;
        } finally {
            pm.close();
        }

        if (game.getGameState() != GameState.WAITING) {
            returnError(response, "This game is either already \"over\" or \"in progress\" and joining is NOT possible");
            return;
        }

        CheckJoinPremissionJSON gameStartJSON = new CheckJoinPremissionJSON();
        gameStartJSON.itendedPlayers = game.getItendedPlayers();
        gameStartJSON.registeredPlayers = game.getRegisteredPlayers();
        gameStartJSON.status = "SUCCESS";
        gameStartJSON.nrOfPlayers = game.getNrOfPlayers();

        response.setContentType("application/json");
        PrintWriter writer = response.getWriter();
        writer.write(gson.toJson(gameStartJSON));
        return;


    }

    private boolean IDinRegisteredList(GameDataJSON registerJSON, Game game) {
        ArrayList<Long> players = game.getRegisteredPlayers();
        for (int i = 0; i < players.size(); i++) {
            Long uid = players.get(i);
            if (uid.equals(registerJSON.playerUID)) {
                return true;
            }
        }
        return false;
    }

    private boolean IDinIntendedList(GameDataJSON registerJSON, Game game) {
        ArrayList<Long> players = game.getItendedPlayers();
        for (int i = 0; i < players.size(); i++) {
            Long uid = players.get(i);
            if (uid.equals(registerJSON.playerUID)) {
                return true;
            }
        }
        return false;
    }

    private void addToItended(GameDataJSON registerJSON, Game game) {
        ArrayList<Long> itended = game.getItendedPlayers();
        itended.add(registerJSON.playerUID);
        game.setItendedPlayers(itended);
    }

    private void addToRegistered(GameDataJSON registerJSON, Game game) {
        ArrayList<Long> itended = game.getRegisteredPlayers();
        itended.add(registerJSON.playerUID);
        game.setRegisteredPlayers(itended);
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
